package com.yb.sys.core.config;

import com.alibaba.fastjson2.JSONObject;
import com.yb.auth.core.handler.AuthAccessDeniedHandler;
import com.yb.auth.core.handler.AuthEntryPointHandler;
import com.yb.auth.core.handler.AuthFailedHandler;
import com.yb.auth.core.filter.AuthTokenFilter;
import com.yb.auth.core.handler.AuthSuccessHandler;
import com.yb.auth.core.config.AuthIgnore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;

import java.util.Objects;

/**
 * Copyright (C), 2022-2022, 姚兵
 * Author: 32210
 * Date: 2022/11/12 21:50
 * FileName: SpringSecurityConfig
 * Description:
 */
@Configuration
@EnableWebSecurity
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig {

    @Autowired
    AuthTokenFilter authTokenFilter;

    @Autowired
    AuthIgnore authIgnore;

    @Autowired(required = false)
    CorsFilter corsFilter;
    @Bean
    SecurityFilterChain configure(HttpSecurity http) throws Exception{
        log.info("authIgnore:{}", JSONObject.toJSONString(authIgnore));
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers( authIgnore.getUrls().toArray(new String[0]))
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().formLogin();
        http.formLogin().successHandler(new AuthSuccessHandler()).failureHandler(new AuthFailedHandler());
        http.exceptionHandling().accessDeniedHandler(new AuthAccessDeniedHandler())
                        .authenticationEntryPoint(new AuthEntryPointHandler());

        http.addFilterBefore(authTokenFilter, UsernamePasswordAuthenticationFilter.class);
        log.info("corsFilter:{}",corsFilter);
        if(Objects.nonNull(corsFilter)){
            http.addFilterBefore(corsFilter,AuthTokenFilter.class);
        }
       return http.build();
    }


    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Autowired
    AuthenticationConfiguration authenticationConfiguration;

    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    @Autowired
    @Lazy
    PasswordEncoder passwordEncoder;
//    @Bean
//    public UserDetailsService users() {
//        String userP = passwordEncoder.encode("user");
//        String adminP = passwordEncoder.encode("admin");
//        System.out.println("userP:"+userP);
//        System.out.println("adminP:"+adminP);
//        UserDetails user = User.builder()
//                .username("user")
//
//                .password(userP)
//                .roles("USER")
//                .build();
//        UserDetails admin = User.builder()
//                .username("admin")
//                .password(adminP)
//                .roles("USER", "ADMIN")
//                .build();
//        return new InMemoryUserDetailsManager(user, admin);
//    }



}
